﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WCS.Infrastructure.Attr;
using WCS.Infrastructure.Dto.Request.Log;
using WCS.Infrastructure.Dto.Request.Organization;
using WCS.Infrastructure.Dto.Response.Common;
using WCS.Infrastructure.EFCore;
using WCS.Infrastructure.IOC;
using WCS.Infrastructure.Tools;
using WCS.Service.Instance;
using WCS.Service.Interface;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace WCS.Service.Instance
{
    [Inject]
    internal class LogService : BaseService, ILogService
    {
        public readonly LogIOC _logIOC;
        public readonly wcsDbContext _dbContext;
        private readonly IConfiguration _configuration;

        public LogService(LogIOC logIOC, wcsDbContext dbContext,IConfiguration configuration)
        {
            _logIOC = logIOC;
            _dbContext = dbContext;
            _configuration = configuration;
        }

        /// <summary>
        /// 记录行为日志
        /// </summary>
        /// <param name="actionLog"></param>
        public async Task WriteAction(ActionLog actionLog)
        {
            await _logIOC._actionLogEFCore.AddAsync(actionLog);
            await _logIOC._actionLogEFCore.SaveChangesAsync();
        }

        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="errorLog"></param>
        public async Task WriteError(ErrorLog errorLog)
        {
            await _dbContext.ErrorLogs.AddAsync(errorLog);
            await _dbContext.SaveChangesAsync();
            //await _logIOC._errorLogEFCore.AddAsync(errorLog);
            //await _logIOC._errorLogEFCore.SaveChangesAsync();
        }

        /// <summary>
        /// 新增错误日志（写数据库 + 本地文件）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddErrorLogAsync(ErrorLogRequestDto dto)
        {
            if (dto == null)
            {
                return GetResult(0, "参数错误");
            }

            // 本地文件输出，参考 ExceptionMiddle
            try
            {
                var basePath = _configuration?["Path:Logs"];
                if (string.IsNullOrWhiteSpace(basePath))
                {
                    basePath = Path.Combine(AppContext.BaseDirectory, "Logs" + Path.DirectorySeparatorChar);
                }
                if (!basePath.EndsWith(Path.DirectorySeparatorChar))
                {
                    basePath += Path.DirectorySeparatorChar;
                }
                Directory.CreateDirectory(basePath);

                string name = DateTime.Now.ToString("yyyyMMdd") + "_error.txt";
                var sb = new StringBuilder();
                sb.Append("时间：").Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append("\r\n");
                sb.Append("url：").Append(dto.Api ?? "").Append("\r\n");
                sb.Append("参数：").Append(dto.Params ?? "").Append("\r\n");
                sb.Append("用户：").Append(dto.UserId ?? "").Append("\r\n");
                sb.Append("错误信息：").Append(dto.Message ?? "").Append("\r\n----------------------------------------------\r\n\r\n");

                await File.AppendAllTextAsync(basePath + name, sb.ToString());
            }
            catch
            {
                // 忽略本地日志写入异常，避免影响主流程
            }

            // 数据库入库
            var entity = new ErrorLog
            {
                Id = Config.GUID(),
                Api = dto.Api,
                CreationTime = DateTime.Now,
                Ip = "",
                Message = dto.Message,
                Params = dto.Params,
                UserId = dto.UserId,
            };

            await _dbContext.ErrorLogs.AddAsync(entity);
            await _dbContext.SaveChangesAsync();

            return GetResult(1);
        }

        /// <summary>
        /// 新增行为日志（写数据库 + 本地文件）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> AddActionLogAsync(ActionLogRequestDto dto)
        {
            if (dto == null)
            {
                return GetResult(0, "参数错误");
            }

            // 本地文件输出，参考 ActionFilter
            try
            {
                var basePath = _configuration?["Path:Logs"];
                if (string.IsNullOrWhiteSpace(basePath))
                {
                    basePath = Path.Combine(AppContext.BaseDirectory, "Logs" + Path.DirectorySeparatorChar);
                }
                if (!basePath.EndsWith(Path.DirectorySeparatorChar))
                {
                    basePath += Path.DirectorySeparatorChar;
                }
                Directory.CreateDirectory(basePath);

                string name = DateTime.Now.ToString("yyyyMMdd") + "_action.txt";
                var sb = new StringBuilder();
                sb.Append("【日志】时间：").Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append("\r\n");
                sb.Append("地址：").Append(dto.ApiUrl ?? "").Append("\r\n");
                sb.Append("分组【").Append(dto.Type ?? "").Append("】行为【").Append(dto.Action ?? "").Append("】\r\n");
                sb.Append("用户【").Append(dto.UserId ?? "").Append("】\r\n");
                sb.Append("参数【").Append(dto.Params ?? "").Append("】");
                sb.Append("结果【").Append(dto.Result?.ToString() ?? "").Append("】message【").Append(dto.ResultMessage ?? "").Append("】 \r\n\r\n");

                await File.AppendAllTextAsync(basePath + name, sb.ToString());
            }
            catch
            {
                // 忽略本地日志写入异常，避免影响主流程
            }

            // 数据库入库
            var action = new ActionLog
            {
                Id = Config.GUID(),
                Action = dto.Action,
                ApiUrl = dto.ApiUrl,
                CreationTime = DateTime.Now,
                Ip = "",
                Params = dto.Params,
                Result = dto.Result,
                ResultMessage = dto.ResultMessage,
                Type = dto.Type,
                UserId = dto.UserId,
                // Version = dto.Version, // 若 DTO 有 Version 字段，可放开
            };

            await _logIOC._actionLogEFCore.AddAsync(action);
            await _logIOC._actionLogEFCore.SaveChangesAsync();

            return GetResult(1);
        }

        /// <summary>
        /// 获取行为日志
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetActionLogsAsync(LogRequestDto dto)
        {
            var data = await _logIOC._actionLogEFCore.QueryAll(out int total, dto.Page, dto.Limit,
                d => (string.IsNullOrEmpty(dto.Key) || d.Action.Contains(dto.Key))
                && (d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime),
                d => d.CreationTime, false).ToListAsync();
            return GetResult(1, data: new
            {
                total,
                data
            });
        }

        /// <summary>
        /// 获取错误日志
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetErrorLogsAsync(LogRequestDto dto)
        {
            var data = await _logIOC._errorLogEFCore.QueryAll(out int total, dto.Page, dto.Limit,
                d => (string.IsNullOrEmpty(dto.Key) || d.Api.Contains(dto.Key))
                && (d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime),
                d => d.CreationTime, false).ToListAsync();
            return GetResult(1, data: new
            {
                total,
                data
            });
        }

        /// <summary>
        /// 获取登录日志
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult> GetLoginLogsAsync(LogRequestDto dto)
        {
            var data = await _logIOC._loginLogEFCore.QueryAll(out int total, dto.Page, dto.Limit,
                d => (string.IsNullOrEmpty(dto.Key) || d.Account.Contains(dto.Key))
                && (d.CreationTime >= dto.StartTime && d.CreationTime <= dto.EndTime),
                d => d.CreationTime, false).ToListAsync();
            return GetResult(1, data: new
            {
                total,
                data
            });
        }

        
    }
}
